package com.mvc.finance.web;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.extremecomponents.table.limit.Limit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.mvc.PdfUtils;
import com.mvc.ProjectUtils;
import com.mvc.base.model.Company;
import com.mvc.base.model.UserNotice;
import com.mvc.config.ApplicationConfig;
import com.mvc.finance.model.ExpenseApply;
import com.mvc.finance.service.ExpenseApplyManager;
import com.mvc.framework.dao.PropertyFilter;
import com.mvc.framework.model.BaseEntity;
import com.mvc.framework.service.DictionaryFacade;
import com.mvc.framework.service.PageManager;
import com.mvc.framework.util.DateUtils;
import com.mvc.framework.util.DomainUtils;
import com.mvc.framework.util.FileUpDownUtils;
import com.mvc.framework.util.FrameworkContextUtils;
import com.mvc.framework.util.PageSearch;
import com.mvc.framework.util.PageUtils;
import com.mvc.framework.web.PageController;
import com.mvc.portal.service.CUserManager;
import com.mvc.portal.service.NotificationManager;
import com.mvc.security.model.User;
import com.mvc.security.service.UserManager;

@Controller
@RequestMapping("expenseApply")
public class ExpenseApplyController extends PageController<ExpenseApply> {

	private static final Logger	LOGGER	= Logger.getLogger(ExpenseApplyController.class);
	@Autowired
	private ExpenseApplyManager	expenseApplyManager;

	@Autowired
	private NotificationManager	notificationManager;

	@Autowired
	private UserManager<User>	userManager;

	@Autowired
	private DictionaryFacade	dictionaryFacade;

	@Autowired
	private CUserManager	    cUserManager;

	@RequestMapping("my")
	public String my(HttpServletRequest request) {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_applyUserId", FrameworkContextUtils.getCurrentUserId() + ""));
		String result = handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "my");
		return result;
	}

	@RequestMapping("print/{orderId}")
	public String print(HttpServletRequest request, @PathVariable Integer orderId) {
		Map<String, Object> model = prepareOrderData(orderId, request);
		String orderContent = notificationManager.getTemplateString("expenseApply.html", model);
		request.setAttribute("orderContent", orderContent);
		return getFileBasePath() + "printExpenseApply";
	}

	@RequestMapping("notify/{orderId}")
	public String notify(@PathVariable Integer orderId, String purchasers, ModelMap modelMap, HttpServletRequest request) {
		boolean result = false;
		try {
			String userEmails = purchasers;
			userEmails += ProjectUtils.EMAIL_SPLIT + request.getParameter("others");
			if (StringUtils.isNotBlank(userEmails)) {
				Map<String, Object> model = prepareOrderData(orderId, request);
				String orderContent = notificationManager.getTemplateString("expenseApply.html", model);
				ExpenseApply order = (ExpenseApply) model.get("entity");
				String[] to = ProjectUtils.getMailTo(userEmails);
				if (to != null && to.length > 0) {
					Company company = order.getCompany();
					String header = ProjectUtils.getPdfHeader(company);
					String footer = ProjectUtils.getPdfFooter(company);
					File file = PdfUtils.htmlToPdf(orderContent, header, footer);
					String subject = "费用申请单(" + company.getName() + ":" + order.getNo() + ")";
					notificationManager.sendMail(subject, ProjectUtils.getCNNoReplyMessage(), new File[] { file },
					        new String[] { order.getNo() + ".pdf" }, to, new String[] {}, true);
					result = true;
				}
			}
		} catch (Exception e) {
			LOGGER.error("notify", e);
		}
		modelMap.addAttribute("result", result);
		return "jsonView";
	}

	@RequestMapping("download/{orderId}")
	public String download(@PathVariable Integer orderId, HttpServletRequest request, HttpServletResponse response) {
		try {
			Map<String, Object> model = prepareOrderData(orderId, request);
			String orderContent = notificationManager.getTemplateString("expenseApply.html", model);
			ExpenseApply order = (ExpenseApply) model.get("entity");
			Company company = order.getCompany();
			String header = ProjectUtils.getPdfHeader(company);
			String footer = ProjectUtils.getPdfFooter(company);
			File file = PdfUtils.htmlToPdf(orderContent, header, footer);
			FileUpDownUtils.setDownloadResponseHeaders(response, order.getNo() + ".pdf");
			FileUpDownUtils.downloadFile(file, response);
		} catch (Exception e) {
			LOGGER.error("download", e);
		}
		return null;
	}

	protected String handleEdit(HttpServletRequest request, HttpServletResponse response, Integer id) throws Exception {
		if (null == id) {
			ExpenseApply entity = new ExpenseApply();
			entity.setObjectId(expenseApplyManager.createSystemId());
			entity.setStatus(ExpenseApply.STATUS_APPLYING);
			request.setAttribute("entity", entity);
		}
		return super.handleEdit(request, response, id);
	}

	protected String handleSave(HttpServletRequest request, ModelMap modelMap, ExpenseApply order) throws Exception {
		if (order.getId() == null) {
			order.setApplyUserId(FrameworkContextUtils.getCurrentUserId());
			order.setGenerateDate(new Date());
			order.setStatus(ExpenseApply.STATUS_APPLYING);
		}
		getEntityManager().save(order);
		if (order.getStatus() == ExpenseApply.STATUS_COMMIT && order.getApplyUserId() == FrameworkContextUtils.getCurrentUserId()) {
			List<User> users = cUserManager.getNoticeUsers(UserNotice.TYPE_ORDER_APPROVAL);
			if (users.size() > 0) {
				String subject = "费用申请单提交通知(" + order.getNo() + ")";
				String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + order.getNo() + "的费用申请单已提交，请您登录<a href='"
				        + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName() + "</a>审批。<br/>"
				        + ProjectUtils.getCommonNoReplyMessage();
				for (User user : users) {
					try {
						notificationManager.sendMail(subject, user.getUserName() + content, new File[] {}, new String[] {},
						        ProjectUtils.getMailTo(user.getEmail()), new String[] {}, false);
					} catch (Exception e) {
						LOGGER.error("sendExpenseApprovalMessages", e);
					}
				}
			}
		}
		return "redirect:edit/" + ((BaseEntity) order).getId() + getMessage("common.base.success", request) + "&action="
		        + request.getParameter("action");
	}

	protected Map<String, Object> prepareOrderData(Integer orderId, HttpServletRequest request) {
		ExpenseApply order = expenseApplyManager.getObject(orderId);
		Map<String, Object> model = new HashMap<String, Object>();
		User applier = userManager.getByObjectId(order.getApplyUserId());
		model.put("deparment", dictionaryFacade.getDictionaryByDictionaryIdAndValue(104, applier.getType()).getName());
		model.put("entity", order);
		model.put("applier", applier);
		request.setAttribute("applier", applier);
		if (order.getApprovalUserId() != null) {
			User auditor = userManager.getByObjectId(order.getApprovalUserId());
			model.put("auditor", auditor);
			request.setAttribute("auditor", auditor);
		}
		model.put("orderItems", order.getExpenseApplyItems());
		model.put("staticDomain", ProjectUtils.getFullCssThemePath());
		model.put("groupName", ApplicationConfig.getGroupName());
		request.setAttribute("entity", order);
		request.setAttribute("staticDomain", ProjectUtils.getFullCssThemePath());
		request.setAttribute("groupName", ApplicationConfig.getGroupName());
		return model;
	}

	protected String handlePage(HttpServletRequest request, PageSearch page) {
		request.setAttribute("users", userManager.getAll());
		request.setAttribute("action", "page");
		return super.handlePage(request, page);
	}

	public String page(HttpServletRequest request, ExpenseApply t, Integer backPage) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("GEI_status", ExpenseApply.STATUS_APPROVAED + ""));
		String result = handlePage(request, page);
		afterPage(request, page, backPage);
		return result;
	}

	@RequestMapping("summary")
	public String summary(HttpServletRequest request) {
		Double totalNeedPay = expenseApplyManager.getTotalNeedPay();
		Double totalPayed = expenseApplyManager.getTotalPayed();
		Date date = new Date();
		Double curentMonthPayed = expenseApplyManager.getTotalPayedByMonth(date);
		date = DateUtils.getLastMonth();
		Double lastMonthPayed = expenseApplyManager.getTotalPayedByMonth(date);
		request.setAttribute("totalNeedPay", totalNeedPay);
		request.setAttribute("totalPayed", totalPayed);
		request.setAttribute("curentMonthPayed", curentMonthPayed);
		request.setAttribute("lastMonthPayed", lastMonthPayed);
		return "finance/expenseSummary";
	}

	@RequestMapping("audit")
	public String audit(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_status", ExpenseApply.STATUS_COMMIT + ""));
		handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "audit");
		return getFileBasePath() + "listExpenseApply";
	}

	@RequestMapping("audit/{expenseApplyId}")
	public String audit(HttpServletRequest request, ModelMap modelMap, @PathVariable Integer expenseApplyId) {
		boolean result = false;
		if (expenseApplyId != null) {
			try {
				ExpenseApply order = expenseApplyManager.getByObjectId(expenseApplyId);
				if (order.getStatus() == ExpenseApply.STATUS_COMMIT) {
					order.setStatus(ExpenseApply.STATUS_APPROVAED);
					order.setApprovalUserId(FrameworkContextUtils.getCurrentUserId());
					expenseApplyManager.save(order);
					User applier = userManager.getByObjectId(order.getApplyUserId());
					String subject = "费用申请单审批完成通知(" + order.getNo() + ")";
					String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + order.getNo() + "的费用申请单申已审批，请您登录<a href='"
					        + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName() + "</a>查看详情。<br/>"
					        + ProjectUtils.getCommonNoReplyMessage();
					try {
						notificationManager.sendMail(subject, applier.getUserName() + content, new File[] {}, new String[] {},
						        ProjectUtils.getMailTo(applier.getEmail()), new String[] {}, false);
					} catch (Exception e) {
						LOGGER.error("sendExpenseApprovedMessages", e);
					}
					result = true;
				}
			} catch (Exception e) {
				LOGGER.error("audit:" + expenseApplyId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@RequestMapping("pay/{expenseApplyId}")
	public String pay(@PathVariable Integer expenseApplyId, ModelMap modelMap, ExpenseApply expenseApply) throws Exception {
		boolean result = false;
		if (expenseApplyId != null) {
			try {
				ExpenseApply order = expenseApplyManager.getByObjectId(expenseApplyId);
				if (order != null && order.getStatus() == ExpenseApply.STATUS_APPROVAED) {
					order.setStatus(ExpenseApply.STATUS_PAYED);
					order.setPayDate(expenseApply.getPayDate());
					order.setBackup(expenseApply.getBackup());
					order.setBackupDate(expenseApply.getBackupDate());
					expenseApplyManager.save(order);
					result = true;
				}
			} catch (Exception e) {
				LOGGER.error("pay:" + expenseApplyId, e);
			}
		}
		modelMap.remove("expenseApply");
		modelMap.addAttribute("result", result);
		return "jsonView";
	}

	@RequestMapping("backward/{orderId}")
	public String backward(HttpServletRequest request, ModelMap modelMap, @PathVariable Integer orderId) {
		boolean result = false;
		if (orderId != null) {
			try {
				ExpenseApply order = expenseApplyManager.getByObjectId(orderId);
				if (order.getStatus() != ExpenseApply.STATUS_PAYED) {
					String reason = request.getParameter("reason");
					order.setStatus(ExpenseApply.STATUS_BACKWARD);
					order.setApprovalUserId(null);
					order.setBackwardReason(reason);
					expenseApplyManager.save(order);
					User applier = userManager.getByObjectId(order.getApplyUserId());
					String subject = "费用申请审批退回通知(" + order.getNo() + ")";
					String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + order.getNo() + "的费用申请单已退回，原因为：" + reason
					        + "。请您登录<a href='" + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName()
					        + "</a>查看详情。<br/>" + ProjectUtils.getCommonNoReplyMessage();
					try {
						notificationManager.sendMail(subject, applier.getUserName() + content, new File[] {}, new String[] {},
						        ProjectUtils.getMailTo(applier.getEmail()), new String[] {}, false);
					} catch (Exception e) {
						LOGGER.error("sendExpenseApplyBackwardMessages", e);
					}
					result = true;
				} else {
					modelMap.addAttribute("message", "已经付款了，不能再修改。");
				}
			} catch (Exception e) {
				LOGGER.error("backward" + orderId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@Override
	public PageManager<ExpenseApply> getEntityManager() {
		return expenseApplyManager;
	}

	@Override
	public String getFileBasePath() {
		return "finance/";
	}

}
